﻿using System;
using System.Runtime.InteropServices;

namespace HlELock.Core
{

    /// <summary>
    /// 封装 MFDLL.dll 提供的门锁系统功能
    /// </summary>
    public class MfLockApi
    {
        // 设置 DLL 路径（默认在程序运行目录或系统路径中）
        private const string DllName = "MFDLL.dll";

        // 1. 响声函数
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int Beep(int Time);

        // 2. 获取卡号
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int GetCardNo(IntPtr cardNo);

        // 3. 初始化连接
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool initconnect(string path);

        // 4. 写客人卡
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int IssueGuestCard(
            string Room,
            string MoreRoom,
            string SubRoom,
            string TLoss,
            string CBgnDate,
            string CEndDate,
            string CNum);

        // 5. 读客人卡
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int ReadGuestCard(
            IntPtr Room,
            IntPtr MoreRoom,
            IntPtr SubRoom,
            IntPtr TLoss,
            IntPtr CBgnDate,
            IntPtr CEndDate,
            IntPtr CNum);

        // 6. 注销客人卡（函数声明中未完整，但按惯例应为 stdcall）
        [DllImport(DllName, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
        public static extern int CancleGuestCard(); // 注意：原函数名拼写为 Cancle（少一个 "e"）
    }



    public class MfLock
    {
        private string _installPath;

        public MfLock(string installPath)
        {
            _installPath = installPath;
        }

        /// <summary>
        /// 初始化连接
        /// </summary>
        public bool InitConnect()
        {
            return !MfLockApi.initconnect(_installPath);
        }

        /// <summary>
        /// 发出响声
        /// </summary>
        public bool Beep(int count)
        {
            return MfLockApi.Beep(count) == 0;
        }

        /// <summary>
        /// 获取当前卡片的物理卡号（十六进制字符串）
        /// </summary>
        public (bool Success, string CardNo) GetCardNo()
        {
            IntPtr ptr = Marshal.AllocHGlobal(64); // 分配 64 字节缓冲区
            try
            {
                int result = MfLockApi.GetCardNo(ptr);
                if (result == 0)
                {
                    string cardNo = Marshal.PtrToStringAnsi(ptr)?.Trim();
                    var cardNumber = int.Parse(cardNo, System.Globalization.NumberStyles.HexNumber);
                    return (true, cardNumber.ToString());
                }
                return (false, null);
            }
            finally
            {
                Marshal.FreeHGlobal(ptr);
            }
        }




        /// <summary>
        /// 写客人卡
        /// </summary>
        /// <param name="room">房号</param>
        /// <param name="moreRoom"> 更多房号，不大于7间</param>
        /// <param name="subRoom">子房号，一般放0</param>
        /// <param name="tLoss">挂失，一般放0</param>
        /// <param name="beginDate">卡片有效起始时间</param>
        /// <param name="endDate">卡片有效结束时间</param>
        /// <param name="cardNum">物理卡号</param>
        /// <returns></returns>
        public CardOperationResult IssueGuestCard(string room, string moreRoom, string subRoom, string tLoss,
            string beginDate, string endDate, string cardNum)
        {
            var result = MfLockApi.IssueGuestCard(room, moreRoom, subRoom, tLoss, beginDate, endDate, cardNum);
            return (CardOperationResult)result;
        }

        /// <summary>
        /// 读客人卡
        /// </summary>
        public (CardOperationResult Result, GuestCardData Data) ReadGuestCard()
        {
            var data = new GuestCardData();

            IntPtr roomPtr = Marshal.AllocHGlobal(64);
            IntPtr moreRoomPtr = Marshal.AllocHGlobal(64);
            IntPtr subRoomPtr = Marshal.AllocHGlobal(64);
            IntPtr tLossPtr = Marshal.AllocHGlobal(64);
            IntPtr beginDatePtr = Marshal.AllocHGlobal(64);
            IntPtr endDatePtr = Marshal.AllocHGlobal(64);
            IntPtr cardNumDatePtr = Marshal.AllocHGlobal(64);

            var result = (CardOperationResult)MfLockApi.ReadGuestCard(
                roomPtr, moreRoomPtr, subRoomPtr, tLossPtr, beginDatePtr, endDatePtr, cardNumDatePtr);

            if (result == 0)
            {
                data.Room = Marshal.PtrToStringAnsi(roomPtr)?.Trim();
                data.MoreRoom = Marshal.PtrToStringAnsi(moreRoomPtr)?.Trim();
                data.SubRoom = Marshal.PtrToStringAnsi(subRoomPtr)?.Trim();
                data.TLoss = Marshal.PtrToStringAnsi(tLossPtr)?.Trim();
                data.BeginDate = Marshal.PtrToStringAnsi(beginDatePtr)?.Trim();
                data.EndDate = Marshal.PtrToStringAnsi(endDatePtr)?.Trim();
                var cardNum = Marshal.PtrToStringAnsi(cardNumDatePtr)?.Trim();
                data.CardNum = int.Parse(cardNum, System.Globalization.NumberStyles.HexNumber).ToString();
            }

            return (result, data);
        }

        /// <summary>
        /// 注销客人卡
        /// </summary>
        public CardOperationResult CancelGuestCard()
        {
            return (CardOperationResult)MfLockApi.CancleGuestCard();
        }
    }

    /// <summary>
    /// 读取的客人卡数据
    /// </summary>
    public class GuestCardData
    {
        public string Room { get; set; }
        public string MoreRoom { get; set; }
        public string SubRoom { get; set; }
        public string TLoss { get; set; }
        public string BeginDate { get; set; }
        public string EndDate { get; set; }
        public string CardNum { get; set; }

        public DateTime BeginTime
        {
            get
            {
                var year = int.Parse("20" + BeginDate.Substring(0, 2));
                var month = int.Parse(BeginDate.Substring(2, 2));
                var day = int.Parse(BeginDate.Substring(4, 2));
                var hour = int.Parse(BeginDate.Substring(6, 2));
                var min = int.Parse(BeginDate.Substring(8, 2));
                var second = int.Parse(BeginDate.Substring(10, 2));
                DateTime dateTime = new DateTime(year, month, day, hour, min, second); // 转为本地时间
                return dateTime;
            }
        }

        public DateTime EndTime
        {
            get
            {
                var year = int.Parse("20" + EndDate.Substring(0, 2));
                var month = int.Parse(EndDate.Substring(2, 2));
                var day = int.Parse(EndDate.Substring(4, 2));
                var hour = int.Parse(EndDate.Substring(6, 2));
                var min = int.Parse(EndDate.Substring(8, 2));
                var second = int.Parse(EndDate.Substring(10, 2));
                DateTime dateTime = new DateTime(year, month, day, hour, min, second); // 转为本地时间
                return dateTime;
            }
        }
        public override string ToString()
        {
            return $"Room:{Room},MoreRoom:{MoreRoom},SubRoom:{SubRoom},TLoss:{TLoss},BeginDate:{BeginDate},EndDate:{EndDate},CardNum:{CardNum}";
        }
    }

    public enum CardOperationResult
    {
        成功 = 0,
        通讯错误 = 1,
        密码长度错误 = 2,
        密码错误 = 3,
        无卡 = 4,
        不是客人卡 = 6,
        更多房号错误 = 7,
        房号空 = 8,
        房号错误 = 9,
        未知错误 = 10
    }
}
